import argparse
import datetime
import logging
import os
from typing import List



from experiment import comparison
from experiment.comparison.models import get_models
from experiment.__main__ import get_parser
from graph.structural import StructuralGraph
from model.case import Case
from utils import silence_third_party
from experiment.simulation import SimDataset
from experiment.comparison.utils import ModelParams


BASE_DIR = os.path.abspath(os.path.dirname(__file__))


def run(args: argparse.Namespace):
    """
    Evaluate multiple models
    """
    data_dir: str = args.data_dir
    report_dir: str = args.report_dir
    os.makedirs(report_dir, exist_ok=True)

    logger = logging.getLogger(__package__)

    logger.info("Loading from %s", data_dir)
    # 设置案例数据参数，查找窗口设为120（2小时）
    case_data_params = dict(
        interval=datetime.timedelta(seconds=15),
        lookup_window=55,
        detect_window=20,
        SLI_cmdb=args.sli_cmdb,  # 使用命令行参数
        SLI_metric=args.sli_metric,  # 使用命令行参数
    )

    # 加载模拟数据集
    logger.info("Loading from %s", data_dir)

    dataset = SimDataset.load(
        folder=data_dir,
        case_data_params=case_data_params,
    )
    cases: List[Case] = []  # 这里创建了空列表，但没有使用 dataset 中的案例

    # 应该使用 dataset 中的案例
    cases = dataset.cases  # 这是正确的用法

    models, graph_factories = get_models(
        graph_factories={"GT": dataset.graph_factory},  # GT: Ground Truth
        params=args.model_params,
        seed=args.seed,
        cuda=args.cuda,
        max_workers=1 if args.cuda else args.max_workers,
    )

    logger.info("Start running on %s with #models=%d", data_dir, len(models))
    comparison.run(
        models=models,
        cases=cases,
        graph_factories=graph_factories,
        output_dir=args.output_dir,
        report_filename=os.path.join(report_dir, "report.csv"),
        delay=300,
        max_workers=1 if args.cuda else args.max_workers,
    )


def wrap_parsers(subparsers: argparse._SubParsersAction):
    """
    Add argparser for your own experiments
    """
    parser_params = dict(formatter_class=argparse.ArgumentDefaultsHelpFormatter)

    # Create base parser with common arguments
    parser = argparse.ArgumentParser(add_help=False, **parser_params)
    parser.add_argument(
        "--data-dir",
        type=str,
        default="/data/Jayx/iscas-rca/results/0408_otel-mysql_net/circa/dataset",
        help="Data directory",
    )
    # Add global arguments to base parser
    parser.add_argument("--cuda", action="store_true", help="Use CUDA (GPU)")
    parser.add_argument(
        "--model-params",
        type=ModelParams,
        required=False,
        help="Provide a json file to specify options for model parameters.",
    )
    parser.add_argument("--seed", type=int, default=519, help="Random seed")
    parser.add_argument(
        "--max-workers",
        type=int,
        default=1,
        help="The number of workers for parallel calculation",
    )
    # 添加 SLI 相关参数
    parser.add_argument(
        "--sli-cmdb",
        type=str,
        default="ingress",
        help="SLI CMDB ID",
    )
    parser.add_argument(
        "--sli-metric",
        type=str,
        default="svc_duration",
        help="SLI metric name",
    )

    # Create run-new subparser with the base parser as parent
    parser_run: argparse.ArgumentParser = subparsers.add_parser(
        "run-new",
        parents=[parser],
        help="Explore all combinations of model parameters",
        **parser_params,
    )
    parser_run.add_argument(
        "--output-dir", type=str, default="output", help="Output directory"
    )
    parser_run.add_argument(
        "--report-dir", type=str, default="report", help="Report directory"
    )
    # 添加 cache-dir 参数
    parser_run.add_argument(
        "--cache-dir", type=str, default="cache", help="Cache directory"
    )
    parser_run.set_defaults(func=run)


def _main():
    parser, subparsers = get_parser()
    wrap_parsers(subparsers)
    parameters = parser.parse_args()

    if parameters.S:
        logging.basicConfig(level=logging.ERROR)
    elif parameters.V:
        logging.basicConfig(level=logging.DEBUG)
    else:
        logging.basicConfig(level=logging.INFO)
    if not parameters.V:
        silence_third_party()

    if "func" in parameters:
        parameters.func(parameters)
    else:
        parser.print_usage()


if __name__ == "__main__":
    _main()
